package com.bwda.dsrs.filecenter.quartz;


import com.bwda.dsrs.filecenter.domain.vo.tsktask.ScheduleJobVo;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * Description 任务管理实现类
 *
 * @author liuxiaoyong
 * @date 2019/11/21
 **/
@Service
public class QuartzServiceImpl implements QuartzService {
    private static Logger logger = LoggerFactory.getLogger(QuartzServiceImpl.class);

    private static SchedulerFactory scheduleFactory = new StdSchedulerFactory();

    /**
     * Description: 添加任务
     *
     * @param job
     */
    @Override
    public void addJob(ScheduleJobVo job) {
        logger.info("begin to addJob : {}", job);
        try {
            Scheduler scheduler = scheduleFactory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());

            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            // 创建并注册一个全局的Job Listener
            // 检测执行了哪些定时任务
            // 不存在，创建一个
            if (null == trigger) {
                Class clazz = Class.forName(job.getBeanClass());

                JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup()).build();

                jobDetail.getJobDataMap().put("scheduleJob", job);

                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());

                trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();

                scheduler.scheduleJob(jobDetail, trigger);
                //启动
                if (!scheduler.isShutdown()) {
                    scheduler.start();
                }
            } else {
                // Trigger已存在，那么更新相应的定时设置
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());

                // 按新的cronExpression表达式重新构建trigger
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

                // 按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, trigger);
            }

            logger.info("addJob successfully.");
        } catch (Exception e) {
            logger.error("addJob failure. error msg: {}", e);
        }
    }

    /**
     * Description: 暂停任务
     *
     * @param job
     */
    @Override
    public void pauseJob(ScheduleJobVo job) {
        logger.info("begin to pauseJob : {}", job);

        try {
            Scheduler scheduler = scheduleFactory.getScheduler();
            JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
            scheduler.pauseJob(jobKey);

            logger.info("pauseJob successfully.");
        } catch (SchedulerException e) {
            logger.error("pauseJob failure. error msg: {}", e);
        }
    }

    /**
     * Description: 恢复任务
     *
     * @param job
     */
    @Override
    public void resumeJob(ScheduleJobVo job) {
        logger.info("begin to resumeJob : {}", job);
        try {
            Scheduler scheduler = scheduleFactory.getScheduler();
            JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());

            scheduler.resumeJob(jobKey);

            logger.info("resumeJob successfully.");
        } catch (SchedulerException e) {
            logger.error("resumeJob failure. error msg: {}", e);
        }
    }

    /**
     * Description: 删除任务
     *
     * @param job
     */
    @Override
    public void deleteJob(ScheduleJobVo job) {
        logger.info("begin to deleteJob : {}", job);
        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
        try {
            Scheduler scheduler = scheduleFactory.getScheduler();
            scheduler.deleteJob(jobKey);

            logger.info("deleteJob successfully.");
        } catch (SchedulerException e) {
            logger.error("deleteJob failure. error msg: {}", e);
        }
    }

    /**
     * Description: 立即执行任务
     *
     * @param job
     */
    @Override
    public void runJob(ScheduleJobVo job) {
        logger.info("begin to runJob : {}", job);
        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
        try {
            Scheduler scheduler = scheduleFactory.getScheduler();
            scheduler.triggerJob(jobKey);

            logger.info("runJob successfully.");
        } catch (SchedulerException e) {
            logger.error("runJobNow failure. error msg: {}", e);
        }
    }

    /**
     * Description: 更新任务执行时间表达式
     *
     * @param job
     */
    @Override
    public void updateJobCron(ScheduleJobVo job) {
        logger.info("begin to updateJobCron : {}", job);
        try {
            Scheduler scheduler = scheduleFactory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(),
                    job.getJobGroup());

            //获取trigger，即在spring配置文件中定义的 bean id="schedulerFactoryBean"
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            //表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());

            //按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

            //按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);

            logger.info("updateJobCron successfully.");
        } catch (SchedulerException e) {
            logger.error("updateJobCron failure. error msg: {}", e);
        }
    }
}
